<?php
/**
 * Created by PhpStorm.
 * User: chniccs
 * Date: 2019-07-20
 * Time: 14:18
 */

namespace app\queue\job;


use app\constant\ActivesConst;
use app\constant\BillConst;
use app\constant\OrderConst;
use app\helper\ActiveHelper;
use app\helper\OrderHelper;
use app\model\AdminActives;
use app\model\AdminActiveSku;
use app\model\AdminOrder;
use app\model\AdminOrderItem;
use app\model\AdminQueueMessage;
use app\queue\QueueTypes;
use think\Db;
use think\Exception;
use think\facade\Log;
use think\queue\Job;

class JobCloseOrder
{

    public function fire(Job $job, $data)
    {
        $orderId = $data['id'];
        print("<info>开始执行，数据为: " . $orderId . "</info> \n");
        $model = AdminOrder::get(['id' => $orderId, 'pay_status' => OrderConst::PAY_STATUS_UN_PAY_ONLINE]);
        if ($model) {
            if ($job->attempts() > 3) {
                //通过这个方法可以检查这个任务已经重试了几次了
                $this->failed($orderId);
                //如果任务执行成功后 记得删除任务，不然这个任务会重复执行，直到达到最大重试次数后失败后，执行failed方法
                $job->delete();
            } else {
                //关闭订单
                Db::startTrans();
                try {
                    //更新订单状态
                    $model->setAttr('trade_status', OrderConst::ORDER_STATUS_CLOSE);
                    $affected = $model->allowField(true)->save();
                    if ($affected) {
                        //回退余额
                        $updateWallet = (new OrderHelper())->reStoreUseWallet([
                            'order_id'=>$model->id,
                            'tid'=>$model->tid,
                            'uid'=>$model->uid,
                            'pay_amount'=>$model->pay_amount,
                            'total_amount'=>$model->total_amount,
                            'type'=>BillConst::TYPE_INCOME,
                            'source'=>BillConst::INCOME_TYPE_REFUND,
                            'desc'=>'订单取消关闭'
                            ]);
                        if(!$updateWallet){
                            throw new \Exception('恢复余额失败');
                        }
                        //恢复产品库存
                        $orderData = $model->getData();
                        //查询的时候还要考虑到有可能订单中的部分sku单品已经退款或不正常状态中了
                        $orderItem = (new AdminOrderItem())->where(['order_id' => $orderData['id'], 'status' => OrderConst::ORDER_ITEM_STATUS_NORMAL])->select();
                        $actives = [];
                        $updateOrderItem = [];
                        foreach ($orderItem as $key => $value) {
                            if (!isset($actives[$value['goods_id'] . ''])) {
                                $actives[$value['goods_id'] . ''] = true;
                            }
                            $updateOrderItem[] = ['id' => $value['id'], 'status' => OrderConst::ORDER_ITEM_STATUS_CLOSE];
                            $done = AdminActiveSku::where(['id' => $value['sku_id']])->setInc('stock', $value['goods_num']);
                            if (!$done) {
                                throw new \Exception('恢复SKU失败');
                            }
                        }
                        //将状态变更为已关闭
                        $orderItemModel = new AdminOrderItem;
                        $orderUpdated = $orderItemModel->saveAll($updateOrderItem);
                        if (!$orderUpdated) {
                            throw new \Exception('变更orderitem状态失败');
                        }
                        //修改产品状态
                        foreach ($actives as $key => $value) {
                            // 这里只更新因为库存卖完而下架的商品状态
                            $model = AdminActives::get(['id' => $key, 'status' => ActivesConst::STATUS_SOLD_OUT]);
                            if ($model) {
                                //并且还要判断时间，是否这个产品已经到了下架时间了
                                $activeData = $model->getData();
                                $activeData = ActiveHelper::changeStatus($activeData);
                                $model->setAttr('status', $activeData['status']);
                                $affected = $model->allowField(true)->save();
                                if (!$affected) {
                                    throw new \Exception('订单关联产品状态修改失败');
                                }
                            }
                        }
                        //更新队列记录
                        $done = AdminQueueMessage::done($data['queue_id']);
                        if(!$done){
                            throw new \Exception('更新队列记录失败');
                        }
                        //全部正常执行完，删除这个消息队列任务
                        $job->delete();
                    }

                    Db::commit();
                } catch (\Exception $e) {
                    //延时3秒执行
                    $job->release(3);
                    Log::write("订单关闭失败" . $orderId . $e->getMessage(), 'error');
                }

                Db::rollback();
            }
        } else {
            $job->delete();
        }
    }

    public function failed($orderId)
    {
        Log::write("订单关闭失败" . $orderId, 'error');
    }

}